2014-10-01 14 views
0

我已经通过网络搜索,但目前为止没有答案,至少没有明确的答案。
假设你是在下列情况下mysql autocommit vs管理员和daos插入方法

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
private void usingManagerTest() 
{ 
    List<SomeType> someList = someDao.findAll(); 
    for (SomeType listItem : someList) 
    { 
     someManager.create(); 
    } 
} 

其中someManager.create()设置一个实体的领域,说someEntity,然后调用someDao.create(someEntity)。
Mysql的记录显示,在每次迭代中,下面的MySQL查询的执行:

set autocommit = 0 
insert into ... 
commit 

现在假设你是在以下情况:

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW) 
private void usingDaoTest() 
{ 
    List<SomeType> someList = someDao.findAll(); 
    for (SomeType listItem : someList) 
    { 
     SomeEntity someEntity = someManager.createEntity(); 
     someDao.create(someEntity); 
    } 
} 

其中createEntity方法调用一些制定者在一个Java实体上,并且创建由DAO执行。这导致如下的mysql日志:

set autocommit = 0 
insert into ... 
insert into ... 
insert into ... 
... 
commit 

其中插入查询的数量是for循环中的迭代次数。

我已经阅读了spring文档,但到目前为止还不清楚为什么会发生这种情况。
任何人都可以解释这种行为?

谢谢

P.S.我知道标题不清楚,欢迎任何建议。

更新:它似乎工作与我所说的不同:从运行usingDaoTest()产生的日志不显示在所有的自动提交查询(这对我没有好处)。
我仍然对理解为什么这两个脚本的工作方式感兴趣,但现在我也对理解如何实现第二个日志结果感兴趣(其中for循环中的所有操作都在autocommit = 0和commit之间执行) 。

再次感谢

UPDATE2:经过一些其他的测试,我了解多一点的@Transactional背后的逻辑,所以我进行了更具体的研究,创立一个解决方案here
这个讨论可以被认为是封闭的,这要归功于所有人。

回答

0

MySQL将在您的事务运行时为您执行操作。 (将自动提交设置为0的原因)在提交事务后,所有更改都将在数据库表上有效地执行,这些更改对其他事务可见。

这是正常情况。但是,有可能定义所执行的更改对其他交易直接可见的交易。这有它的缺点。

+0

谢谢,但我仍然没有理由。我没有调用显式的提交调用,我只是调用dao create:第一次通过管理器,第二次直接进入循环。创建应该使用hibernate调用提交,并且这两种情况都发生在一个循环中,为什​​么它们的行为不同? Plus两个方法都被定义为propagation.requires_new,因此它们应该为循环使用相同的事务。 我省略了也dao.create()有@transactional注释但传播。需求。 – 2014-10-01 09:07:49