第一类丢失更新
某一个事务的回滚,导致另外一个事务已更新的数据丢失了。
第二类丢失更新
某一个事务的提交,导致另外一个事务已更新的数据丢失。
脏读
某一事务读取了另外一个事务未提交的数据。
不可重复读
某一事务,对同一个数据前后的读取结果不一致。
幻读
某一个事务,对同一个表前后查询到的行数不一致。
事务隔离级别
--------------------------------------------------------------------------------------------------------------------------------
悲观锁(顾名思义看待问题很悲观,认为如果并发就一定有问题)
共享锁(S锁)
事务A对某数据加了共享锁后,其他事务只能对该数据加共享锁,但不能加排他锁。
排他锁(X锁)
事务A对某数据加了排他锁后,其他事务对该数据既不能加共享锁,也不能加排他锁。
乐观锁(自定义,看待问题乐观,认为即使并发了通常也不会有问题)
版本号、时间戳等
在更新数据前,检查版本号是否发生变化。若发生变化则取消本次更新,否则就更新数据(版本号+1)。
---------------------------------------------------------------------------------------------------------------------------------
Spring事务管理
-声明式事务
1、通过XML配置,声明某方法的事务特征
2、通过注解,声明某方法的事务特征
-编程式事务
通过TransactionTemplate管理事务,并通过它执行数据库的操作
以下是代码案例:
(故意制造了一个错误Integer.valueOf("avc")进行检测)
//REQUIRED:支持当前事务 A调B A就是当前事务,如果A没有事务,则创建新事物
//REQUIRES_NEW:创建一个新事物,并且暂停当前事务
//NESTED:如果当前存在事务,则嵌套在该事务中执行(独立的提交和回滚),否则如果没有事务,则创建新事物
@Transactional(isolation = Isolation.READ_COMMITTED,propagation = Propagation.REQUIRED)//事务传播机制 业务方法A调用业务方法b,以谁的事务机制为准(解决交叉问题)
public Object save1() {
//新增用户
User user = new User();
user.setUsername("alpha");
user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
user.setEmail("alpha@qq.com");
user.setHeaderUrl("http://images.nowcoder.com/head/99t.png");
user.setCreateTime(new Date());
userMapper.insertUser(user);
//新增帖子
DiscussPost discussPost = new DiscussPost();
discussPost.setUserId(user.getId());
discussPost.setTitle("Discussion");
discussPost.setContent("Welcome");
discussPost.setCreateTime(new Date());
discussPostMapper.insertDiscussPost(discussPost);
Integer.valueOf("avc");
return "ok";
}
public Object save2(){
transactionTemplate.setIsolationLevel(TransactionTemplate.ISOLATION_READ_COMMITTED);
transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
return transactionTemplate.execute(new TransactionCallback<Object>() {
@Override
public Object doInTransaction(TransactionStatus transactionStatus) {
//新增用户
User user = new User();
user.setUsername("alpha");
user.setSalt(CommunityUtil.generateUUID().substring(0, 5));
user.setPassword(CommunityUtil.md5("123" + user.getSalt()));
user.setEmail("alpha@qq.com");
user.setHeaderUrl("http://images.nowcoder.com/head/99t.png");
user.setCreateTime(new Date());
userMapper.insertUser(user);
//新增帖子
DiscussPost discussPost = new DiscussPost();
discussPost.setUserId(user.getId());
discussPost.setTitle("Discussion");
discussPost.setContent("Welcome");
discussPost.setCreateTime(new Date());
discussPostMapper.insertDiscussPost(discussPost);
Integer.valueOf("avc");
return "ok";
}
});
---------------------------------------------------------------------------------------------------------------------------------