Hibernate Entity管理器在查询之前自动刷新并在事务中提交对DB的更改

Qui*_*ncy 3 hibernate transactions entitymanager hibernate-entitymanager jpa-2.0

我在Jboss AS 6.0.0 final上使用Hibernate 3.6.0和JPA 2.在我的EJB中,有一种方法可以更新实体值并对其进行一些查询.整个方法在BMT事务中运行.如果有任何失败,所有更改都应该回滚,而不是提交给DB.

数据库是mySql.

在运行JPA查询之前,JPA会自动将更改的状态刷新到DB,以防止任何过时的数据返回.但是,在我的方法中,自动刷新直接更新并将更改提交到DB,甚至之后出现了错误,更改不会回滚.所以我想问一下我的设置中是否有错误的配置,或者这是一个错误或什么的.

EJB

@Stateless(mappedName = "MyManagementBean")
    @Local
    @TransactionManagement(TransactionManagementType.BEAN)


    public class MyManagement implements MyManagementLocal,MyManagementRemote {

        @PersistenceUnit(unitName="MyEjb") EntityManagerFactory emf;
        @Resource UserTransaction utx;
        @Resource SessionContext ctx;

        /**
         * Default constructor. 
         */
        public MyManagement () {
            // TODO Auto-generated constructor stub
        }

        public void dosomething(String id) throws Exception
        {

            try {
                utx.begin();    
                em = emf.createEntityManager();

                Myline line = em.find(Myline.class, id);

                line.setStatus("R");

            Stromg q += " from Myline as line ";             
                //auto flush apply here and directly committed to DB...
            Iterator iter = em.createQuery(q).getResultList().iterator();

                em.flush();
                utx.commit();// changes should only commit after this
            }
            catch (Exception e) {
                e.printStackTrace();
                if (utx != null) utx.rollback();
                throw e; // or display error message
            }
            finally {
                em.close();
            }       
        } 
}
Run Code Online (Sandbox Code Playgroud)

persistence.xml中

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
    <persistence-unit name="MyEjb" transaction-type="JTA">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <jta-data-source>java:MyDS</jta-data-source>
        <class>com.quincy.entity.MyLine</class>

        <properties>
            <property name="hibernate.connection.defaultNChar" value="true"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLMyISAMDialect"/>
            <property name="hibernate.ejb.cfgfile" value="META-INF/hibernate.cfg.xml"/>
        </properties>
    </persistence-unit>
</persistence>
Run Code Online (Sandbox Code Playgroud)

的hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>


        <property name="transaction.manager_lookup_class">org.hibernate.transaction.JBossTransactionManagerLookup</property>


        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>       

        <property name="hibernate.max_fetch_depth">3</property>


    </session-factory>
</hibernate-configuration>
Run Code Online (Sandbox Code Playgroud)

的mysql-ds.xml文件

<datasources>

<local-tx-datasource>
    <jndi-name>MyDS</jndi-name>
    <connection-url>jdbc:mysql://10.10.150.57:3306/myds</connection-url>
    <driver-class>com.mysql.jdbc.Driver</driver-class>
    <user-name>user</user-name>
    <password>pwd</password>
    <exception-sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.MySQLExceptionSorter</exception-sorter-class-name>
    <metadata>
       <type-mapping>mySQL</type-mapping>
    </metadata>
  </local-tx-datasource>
</datasources>
Run Code Online (Sandbox Code Playgroud)

经过进一步的调查,我发现当有一个刷新时,脏的更改会被写入并直接提交给DB.如果我删除flush(),一切正常.但是,在查询之前有系统触发的刷新,我认为这是必要的.

在我看来,db是自动提交的.我试图将属性设置hibernate.connection.autocommitfalse但问题只是持续存在,并且提示违反规范的EJB警告.

更新:原因应该来自mysql.好像我切换到mssql服务器,问题消失了.我也试过mysql xa-datasource,仍然没有运气...

Qui*_*ncy 5

问题解决了.原因是mysql中的表MyISAM默认使用引擎,而使用此引擎的表不支持事务.切换表innoDB使事情有效.希望这对任何人都有用,所以他们不会浪费我那么多的时间.:(