@Transactional(propagation=Propagation.REQUIRED,rollbackFor = Exception.class) 已经有事务则直接加入,没有事务则新建事务;遇到异常则回滚
@Transactional(propagation=Propagation.REQUIRED) :如果有事务, 那么加入事务, 没有的话新建一个(默认情况下)
@Transactional(propagation=Propagation.NOT_SUPPORTED) :容器不为这个方法开启事务
@Transactional(propagation=Propagation.REQUIRES_NEW) :不管是否存在事务,都创建一个新的事务,原来的挂起,新的执行完毕,继续执行老的事务
@Transactional(propagation=Propagation.MANDATORY) :必须在一个已有的事务中执行,否则抛出异常
@Transactional(propagation=Propagation.NEVER) :必须在一个没有的事务中执行,否则抛出异常(与Propagation.MANDATORY相反)
@Transactional(propagation=Propagation.SUPPORTS) :如果其他bean调用这个方法,在其他bean中声明事务,那就用事务.如果其他bean没有声明事务,那就不用事务.
@Transactional(timeout=30) //默认是30秒
@Transactional(isolation = Isolation.READ_UNCOMMITTED):读取未提交数据(会出现脏读, 不可重复读) 基本不使用
@Transactional(isolation = Isolation.READ_COMMITTED):读取已提交数据(会出现不可重复读和幻读)
@Transactional(isolation = Isolation.REPEATABLE_READ):可重复读(会出现幻读)
@Transactional(isolation = Isolation.SERIALIZABLE):串行化
MYSQL: 默认为REPEATABLE_READ级别
SQLSERVER: 默认为READ_COMMITTED
用 spring 事务管理器,由spring来负责数据库的打开,提交,回滚.默认遇到运行期例外(throw new RuntimeException("注释");)会回滚,即遇到不受检查(unchecked)的例外时回滚;而遇到需要捕获的例外(throw new Exception("注释");)不会回滚,即遇到受检查的例外(就是非运行时抛出的异常,编译器会检查到的异常叫受检查例外或说受检查异常)时,需我们指定方式来让事务回滚要想所有异常都回滚,要加上 @Transactional( rollbackFor={Exception.class,其它异常}) .
、@Transactional 注解应该只被应用到 public 可见度的方法上。 如果你在 protected、private 或者 package-visible 的方法上使用 @Transactional 注解,它也不会报错, 但是这个被注解的方法将不会展示已配置的事务设置。
http://www.cnblogs.com/caoyc/p/5632963.html
Ssm框架下使用数据库的事物:
首先确认数据库的引擎类型,如果是myisam则不支持使用事物,修改为InnoDB支持事物.
show engines;//查看数据库引擎 类型
alter table task_baseinfo type=innodb;//修改task_baseinfo引擎类型为innodb
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
2)对公共方法增加事物管理
// @Transactional(readOnly=false,propagation=Propagation.REQUIRED,rollbackFor = Exception.class)
@Transactional
@Override
public int saveTaskBaseInfo(int taskId, String taskName, int taskType,
int funcNum, String lastModifiedUser,String allbefroeTaskId, String startDate,int startTime,int endTime) {
// 如果任务中包含有 taskId则执行修改
//新插入执行的操作
int newTaskId=getMaxTaskId()+1;
taskId = newTaskId ;
HashMap
map.put("table_name", "task_baseinfo");
map.put("col_name", "task_id,task_name,task_type,create_time,last_modified_user,isdel");
map.put("col_value", "("+newTaskId+",'"+taskName+"',"+taskType+",'"+DateUtil.getNowDateAsStr()+"','"+lastModifiedUser+"'"+",0"+")");
mysqlAlterService.addRecord(map);//第一个插入操作
int recode=taskTimeInfoService.insertTaskTimeInfo(taskId, startDate, startTime, endTime);//第二个插入操作,如果插入有问题,则返回的值为负数
if(recode<0){
throw new RuntimeException("该任务的定时信息插入失败...");//此处抛出的RuntimeException十分重要,只有抛出了该异常才会调用事物管理,此时抛出运行时异常说明第二个插入有问题.所以两个插入均失败;虽然第一个插入操作已经执行,但是此时会自动回滚.
}
return 1000;
}