Java 在交易中打开/关闭连接的后果是什么?

Java 在交易中打开/关闭连接的后果是什么?,java,spring,transactions,glassfish,ejb,Java,Spring,Transactions,Glassfish,Ejb,我试着总结一下一些奇怪的错误,似乎应该作为一个事务运行的代码却没有。我会试着把所有相关的部分都记下来,但事实上确实如此 该项目同时包含Spring和EJB,因此我不确定这里是否实际使用了其中一个,或者两者都使用 Spring配置包含以下内容: <jee:jndi-lookup id="platformTransactionManager" jndi-name="java:appserver/TransactionManager" resource-ref="false"

我试着总结一下一些奇怪的错误,似乎应该作为一个事务运行的代码却没有。我会试着把所有相关的部分都记下来,但事实上确实如此

该项目同时包含Spring和EJB,因此我不确定这里是否实际使用了其中一个,或者两者都使用

Spring配置包含以下内容:

<jee:jndi-lookup id="platformTransactionManager" jndi-name="java:appserver/TransactionManager" resource-ref="false"
                 expected-type="javax.transaction.TransactionManager" lookup-on-startup="false"/>

<bean id="transactionManager"
      class="org.springframework.transaction.jta.JtaTransactionManager" lazy-init="true">
    <constructor-arg ref="platformTransactionManager"/>
    <property name="autodetectUserTransaction" value="false"/>
    <property name="allowCustomIsolationLevels" value="true"/>
</bean>

<tx:annotation-driven/>
最后,调用上述方法的类(没有无聊的SOAP内容):

我这里有几个问题:

  • 将创建哪些交易记录(如果有)?
    • transactionManager在这里是使用Spring定义的,还是仅使用glassfish jndi定义的
  • 假设通过insertSomething方法执行事务:
    • 当连接在事务中关闭时(插入1),查询会发生什么情况
    • 如果连接关闭后(插入1后)出现错误,会发生什么情况
    • 是否有可能将insert 2提交给数据库,而insert 1不提交给数据库?如果是,怎么做?(这是我实际调试的错误)
  • 使用
    SQLServerXADataSource
    getConnection()
    会产生什么后果?
    • 我们是否有XA(我假设您必须使用XA相关的方法之一来获得连接)
    • 我们是否有连接池(
      getConnection()
      调用池变量设置为null的内部方法)

  • 如果你认为这个问题很混乱,你应该看看我基于它的项目;)

    由于您在创建时将jee Transactionmanager作为参数提供给spring Transactionmanager,因此这是最重要的。您应该知道,只要您在jta中工作,连接的生命周期就完全通过Transactionmanager处理。以其他方式创建或关闭的连接不会参与tramanager管理的连接。通常情况下,你不应该做到这一点。因此:如何创建数据源。您提供的源将使其处于未初始化状态。
    @Stateless
    @ApplicationException(rollback = true)
    @TransactionManagement(TransactionManagementType.CONTAINER)
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @Local(MyLocal.class)
    @Remote(MyRemote.class)
    @EJB(beanInterface = MyLocal.class, name = "java:app/MyEJB", beanName = "MyEJB")
    public class MyEJB {
        public void insertSomething(final Something something) {
            final com.microsoft.sqlserver.jdbc.SQLServerXADataSource dataSource;
            final SomethingElse somethingElse = something.getSomethingElse();
            //insert 1
            try {
                final String sql = convertToInsertSql(somethingElse);           
                dataSource = //gets the datasource from Glassfish via JNDI
                final Connection conn = dataSource.getConnection();
                final Statement stmt = conn.createStatement();
                stmt.execute(sql);
                //this is actually wrapped in a method that returns the id of created row
                //I have removed this for brevity, but assume that you get that back
            } finally {
                conn.close();
            }
    
            something.getSomethingElse().setId(/* id from the result above */)
    
            // insert 2
            try {
                final String sql = convertToInsertSql(something);           
                dataSource = //gets the datasource from Glassfish via JNDI
                final Connection conn = dataSource.getConnection();
                final Statement stmt = conn.createStatement();
                stmt.execute(sql);
            } finally {
                conn.close();
            }
        }
    }
    
    public class MyService extends SpringBeanAutowiringSupport {
    
        @Inject
        private MyLocal myLocal;
    
        public void createSomething(/*stuff*/) {
            /* more stuff */
            myLocal.insertSomething(something);
        }
    }