最近在做项目的时候用到事务,我使用的是SSM框架,也就是Spring + SpringMVC + Mybatis 框架,配置事务的时候是用注解的方式,连接的数据库是MySQL数据库!
先说一下事务:简单理解,事务就是控制两个数据库操作同时成功或者同时失败,例如转账,要么转账成功要么转账失败,成功就是一个账号减了钱,另一个账号加了钱,这是两个数据库操作,失败的话,也不能是转出的账号少了钱,收入的账号缺没有收到钱!这样转出的人会疯掉!只能是回滚操作,让转出的账号钱回滚到没转以前一样!
接下来说说SSM框架事务的配置吧!在spring的配置文件中 配置如下:
<!--
4. 事务管理 : DataSourceTransactionManager dataSource:引用上面定义的数据源
-->
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 5. 使用声明式事务
transaction-manager:引用上面定义的事务管理器
-->
<tx:annotation-driven transaction-manager="txManager" />
第五点配置了声明式事务之后,在service层就可以使用注解了,很简单,代码如下配置@Transactional 就是给该方法加了事务控制了
@Transactional(readOnly = false, propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public String sendGiftService(int sendId, String anchAccount, int ticket,int live_record_id, int gift_id) throws Exception {
....
}
事务一定是在执行数据库语句发生异常的时候才会触发事务,如果需要根据实际业务触发事务的话,需要手动抛出异常才能触发事务,例如
//扣款deduct
i = pocketInfoMapper.deductDiamondByUserid(ticket, sendId);
j = pocketInfoMapper.increaseTicketByUserid(ticket, anchUserid);//加钱
第一句是扣钱操作,第二句是加钱操作,但是就算是加钱没有成功(update 语句)并没有发生异常, j返回的是0 这样不会触发事务回滚,那就要判断
if(j==0){
throw new RuntimeException("收款不成功,出现异常了");
}
这样手动抛出异常,而且这里面不能去try catch,抛出到controller层去捕获的话,这样事务就可以触发了,自动回滚!
到这里ssm框架的事务配置是没错的,但是我还是失败了,试了很久之后,不得其姐,有一位神秘的大神告诉我,有可能跟数据库有关系!
MYsql 数据库引擎如果是MyISAM 它是不支持事务的,要修改数据库引擎为 INNODB 这样才会支持事务回滚。
修改数据库引擎的方法如下:
查看mysql存储引擎命令,在mysql>提示符下搞入show engines;字段 Support为:Default表示默认存储引擎
2、设置InnoDB为默认引擎:在配置文件my.cnf中的 [mysqld] 下面加入default-storage-engine=INNODB 一句
3、重启mysql服务器:mysqladmin -u root -p shutdown或者service mysqld restart 登录mysql数据库,
经过测试,发现事务真的可以回滚了,好开心好开心!