为什么mybatis 批量提交插入一条数据的时候必须的提交事务

匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。spring+mybatis,Support事务传播级别下无法及时拿到新插入数据的问题 - ITeye问答
Spring+Mybatis,事务配置是按照官网上配的
&bean id="dataSource" class="com.mchange.boPooledDataSource"&&
&&&&&&&&&&& destroy-method="close"&&
&&&&&&& &property name="driverClass" value="${jdbc.driverClassName}" /&&
&&&&&&& &property name="jdbcUrl" value="${jdbc.url}" /&&
&&&&&&& &property name="user" value="${jdbc.username}" /&&
&&&&&&& &property name="password" value="${jdbc.password}" /&&
&&&&&&& &property name="initialPoolSize" value="${c3p0.initialPoolSize}" /&&
&&&&&&& &property name="minPoolSize" value="${c3p0.minPoolSize}" /&&
&&&&&&& &property name="maxPoolSize" value="${c3p0.maxPoolSize}" /&&
&&&&&&& &property name="acquireIncrement" value="${c3p0.acquireIncrement}" /&&
&&&&&&& &property name="maxIdleTime" value="${c3p0.maxIdleTime}" /&&
&&&&&&& &property name="maxStatements" value="${c3p0.maxStatements}" /&&
&&& &/bean&&
&&& &!-- 把数据源通过spring注入mybatis的sqlSessionFactory --&
&&& &bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&
&property name="dataSource" ref="dataSource" /&
&!-- ScanMapperFiles,自动扫描所有Mapper映射文件 --&
&bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"&
&property name="basePackage" value="com.bigplayer.test.mapper" /&
&!-- 事务处理管理器 ,事务管理器指定的 DataSource 必须和用来创建 SqlSessionFactoryBean 的 是同一个数据源,否则事务管理器就无法工作了--&
&bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&
&
&property name="dataSource" ref="dataSource" /&
&!-- 定义事务的管理者 --&
&tx:advice id="txAdvice" transaction-manager="transactionManager"&
&!-- 定义使用事务的方法特征行为 --&
&tx:attributes&
&tx:method name="delete*" propagation="REQUIRED" read-only="false"
&&&&&&&&&&&&&&&&&&&&&&&&&&& rollback-for="java.lang.Exception" no-rollback-for="java.lang.RuntimeException"/&
&&&&&
&tx:method name="insert*" propagation="REQUIRED" read-only="false"
&&&&&&&&&&&&&&&&&&&&&&&&&&& rollback-for="java.lang.RuntimeException" /&
&tx:method name="update*" propagation="REQUIRED" read-only="false"
&&&&&&&&&&&&&&&&&&&&&&&&&&& rollback-for="java.lang.Exception" /&
&&&&&
&tx:method name="find*" propagation="SUPPORTS"/&
&tx:method name="get*" propagation="SUPPORTS"/&
&tx:method name="select*" propagation="SUPPORTS"/&
&tx:method name="*" propagation="SUPPORTS" /&
&/tx:attributes&
&/tx:advice&
&!-- 配置事务切入点 --&
&aop:config&
&!--把事务控制在Service层--&
&aop:pointcut id="bussinessService"
expression="execution(public
* com.bigplayer.test.service.*.*(..))" /&
&!-- 指定bussinessService切入点应用txAdvice处理器,即该切入点的所有符合特征的方法均具备了事务性 --&
&aop:advisor pointcut-ref="bussinessService" advice-ref="txAdvice" /&
&/aop:config&
注意这句&tx:method name="*" propagation="SUPPORTS" /&
然后我先弄了一个TestService接口,只有一个方法testDao()
而后弄了一个UserInfoService接口
public abstract void insertUserRegister(UserInfo userInfo);
public abstract UserInfo selectUserLogin(Integer id);
public abstract List&UserInfo& selectAllUser();
public abstract void updateUserInfo(UserInfo userInfo);
然后分别实现了TestService接口和UserInfoService接口,其中UserInfoService接口的实现类UserInfoServiceImpl的四个方法在独立工作时都是正常的
TestService的TestServiceImpl实现类的方法内容是这样的
private UserInfoService userInfoS
public UserInfoService getUserInfoService() {
return userInfoS
&&& @Resource
public void setUserInfoService(UserInfoService userInfoService) {
this.userInfoService = userInfoS
public UserInfo testDao() {
UserInfo userInfo = userInfoService.selectUserLogin(1);
//此时数据库时空的,查到的数据为null
if (userInfo != null) {
logger., userInfo.getUserName());
logger., "不存在该数据");
UserInfo userInfo2 = new UserInfo();
userInfo2.setUserName("4sdzfasrtxdh56");
userInfo2.setPassword("asafdsfdf");
userInfoService.insertUserRegister(userInfo2);
//插入新数据
userInfo = userInfoService.selectUserLogin(1);
//再次查询
if (userInfo != null) {
logger., userInfo.getUserName());
logger., "不存在该数据");
外部调用这段代码
public static void main(String[] args) {
System.out.println( "Hello Mybatis!" );
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
TestService testService = context.getBean(TestService.class);
testService.testDao();
//logger., testService.selectUserLogin(1).getUserName());
这段代码,就是简单的先查询数据库中不存在的一个数据,而后插入这个数据,再次查询这行数据
根据单独测试表明,执行插入数据库,数据库里立即就有了数据,但是,奇怪的是,selectUserLogin查不出来。
想修正这个问题也很简单,事务配置的那句&tx:method name="*" propagation="SUPPORTS" /&,不传播级别由SUPPORTS改成REQUIRED立即迎刃而解。
但是我想不清楚理由,TestServiceImpl由spring生成,它内部的userInfoService肯定被事务增强过,因此插入调用时应该立即起效,单步测试证明也确实起效了,而TestService此时本身是工作在SUpport传播级别下的,为什么此时它调用了同样是SUPPORT级别的userInfoService.selectUserLogin方法,会查不出刚刚插入的数据,userInfoService.insertUserRegister本身已经被事务加强,调用结束时就应该插入完毕了。原因到底在哪里
问题补充:补充一点,通过观察sql语句发现,第二次查询的时候mybatis并没有去查数据库,而是直接从缓存里取的数据。也就是说这更像是缓存没有被更新。进一步测试表明,把insert换成update,却一切正常,能得到更新的数据
如果当前在事务中,即以事务的形式运行,如果当前不再一个事务中,那么就以非事务的形式运行
这就跟平常用的普通非事务的代码只有一点点区别了。
应该是你的插入方法和select方法 不在事物里面的
所以没有查到
你用的是什么数据库?还有能否把UserInfoService的实现代码粘上来看看。
我这里测试是没有问题的,是可以读到刚刚插入的数据的。只不过我这里使用的是@Transactional的注解。
已解决问题
未解决问题为什么我的mybatis是默认 自动提交的呢
当我直接 commit的时候(没写sqlSession.close()),控制台出日志了, 但是数据库没有更改。去掉commit也一样。而当我 在commit后面加上 sqlSession.close()后, 数据库更改了。去掉commit,数据库也会更改。public static void main(String[] args) {
delete(5);
List&Student& list = queryStudentByID(new Student(5, 12, "li"));
System.out.println(list);
public static void delete(int id) {
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession =
sqlSession = dbAccess.getSqlSession();
sqlSession.selectList("Student.delete", id);
//sqlSession.close();控制台DEBUG [main] - ==&
Preparing: DELETE FROM student WHERE id =? DEBUG [main] - ==& Parameters: 5(Integer)DEBUG [main] - ==&
Preparing: SELECT * FROM student WHERE id = ? DEBUG [main] - ==& Parameters: 5(Integer)DEBUG [main] - &==
Total: 1[Student [id=5, age=14, name=li]]
没注意到后面改成了delete
写下你的评论...
Copyright (C)
All Rights Reserved | 京ICP备 号-2在mybatis有声明式事务中强制提交事务_百度知道
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。
在mybatis有声明式事务中强制提交事务
我有更好的答案
不明白你的提问....
在声明式事务是监听一个类的方法,我就是想在方法没有执行完就提交事务,如果方法后面抛runtime异常也不回滚前面的东西
在声明式事务是监听一个类的方法,我就是想在方法没有执行完就提交事务,如果方法后面抛runtime异常也不回滚前面的东西
采纳率:70%
事务处理你理解吧! 不明白 你为什么 要在方法没有执行完就提交事务,能详细的说明一下吗?相互学习一下。
为您推荐:
其他类似问题
mybatis的相关知识
等待您来回答博客分类:
1. myBatis单独使用时,使用SqlSession来处理事务:
public class MyBatisTxTest {
private static SqlSessionFactory sqlSessionF
private static R
@BeforeClass
public static void setUpBeforeClass() throws Exception {
reader = Resources.getResourceAsReader("Configuration.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} finally {
if (reader != null) {
reader.close();
public void updateUserTxTest() {
SqlSession session = sqlSessionFactory.openSession(false); // 打开会话,事务开始
IUserMapper mapper = session.getMapper(IUserMapper.class);
User user = new User(9, "Test transaction");
int affectedCount = mapper.updateUser(user); // 因后面的异常而未执行commit语句
User user = new User(10, "Test transaction continuously");
int affectedCount2 = mapper.updateUser(user2); // 因后面的异常而未执行commit语句
int i = 2 / 0; // 触发运行时异常
mit(); // 提交会话,即事务提交
} finally {
session.close(); // 关闭会话,释放资源
2. 和Spring集成后,使用Spring的事务管理:
a. @Transactional方式:
在类路径下创建beans-da-tx.xml文件,在beans-da.xml(系列五)的基础上加入事务配置:
&!-- 事务管理器 --&
&bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"&
&property name="dataSource" ref="dataSource" /&
&!-- 事务注解驱动,标注@Transactional的类和方法将具有事务性 --&
&tx:annotation-driven transaction-manager="txManager" /&
&bean id="userService" class="com.john.hbatis.service.UserService" /&
@Service("userService")
public class UserService {
@Autowired
public int batchUpdateUsersWhenException() { // 非事务性
User user = new User(9, "Before exception");
int affectedCount = mapper.updateUser(user); // 执行成功
User user2 = new User(10, "After exception");
int i = 1 / 0; // 抛出运行时异常
int affectedCount2 = mapper.updateUser(user2); // 未执行
if (affectedCount == 1 && affectedCount2 == 1) {
@Transactional
public int txUpdateUsersWhenException() { // 事务性
User user = new User(9, "Before exception");
int affectedCount = mapper.updateUser(user); // 因后面的异常而回滚
User user2 = new User(10, "After exception");
int i = 1 / 0; // 抛出运行时异常,事务回滚
int affectedCount2 = mapper.updateUser(user2); // 未执行
if (affectedCount == 1 && affectedCount2 == 1) {
在测试类中加入:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:beans-da-tx.xml" })
public class SpringIntegrateTxTest {
UserService userS
public void updateUsersExceptionTest() {
userService.batchUpdateUsersWhenException();
public void txUpdateUsersExceptionTest() {
userService.txUpdateUsersWhenException();
b. TransactionTemplate方式
在beans-da-tx.xml中添加:
&bean id="txTemplate" class="org.springframework.transaction.support.TransactionTemplate"&
&constructor-arg type="org.springframework.transaction.PlatformTransactionManager" ref="transactionManager" /&
在UserService类加入:
@Autowired(required = false)
TransactionTemplate txT
public int txUpdateUsersWhenExceptionViaTxTemplate() {
int retVal = txTemplate.execute(new TransactionCallback&Integer&() {
public Integer doInTransaction(TransactionStatus status) { // 事务操作
User user = new User(9, "Before exception");
int affectedCount = mapper.updateUser(user); // 因后面的异常而回滚
User user2 = new User(10, "After exception");
int i = 1 / 0; // 抛出运行时异常并回滚
int affectedCount2 = mapper.updateUser(user2); // 未执行
if (affectedCount == 1 && affectedCount2 == 1) {
return retV
在SpringIntegrateTxTest类中加入:
public void updateUsersWhenExceptionViaTxTemplateTest() {
userService.txUpdateUsersWhenExceptionViaTxTemplate(); //
注:不可catch Exception或RuntimeException而不抛出:
@Transactional
public int txUpdateUsersWhenExceptionAndCatch() { // 事务性操作,但是外围框架捕获不到异常,认为执行正确而提交。
User user = new User(9, "Before exception");
int affectedCount = mapper.updateUser(user); // 执行成功
User user2 = new User(10, "After exception");
int i = 1 / 0; // 抛出运行时异常
int affectedCount2 = mapper.updateUser(user2); // 未执行
if (affectedCount == 1 && affectedCount2 == 1) {
} catch (Exception e) { // 所有异常被捕获而未抛出
e.printStackTrace();
浏览 76314
[lis[color=indigo][/color]t][img][/img][/list]
浏览: 750711 次
来自: 杭州
这个。。是api说明吧。。
请问大文件如何处理?按你这种方式的话,文件超过200M时就会报 ...
lwj1113 写道谢谢博主这么细致的在系列五中通过 ...
谢谢博主这么细致的在系列五中通过testng测试类跑 ...

我要回帖

更多关于 mybatis设置自动提交 的文章

 

随机推荐