mysql事物行级锁_Mysql的事务及行级锁

转自:http://www.cnblogs.com/edwinchen/p/4171866.html

以签到为例,每个用户每天只能签到一次,那么怎么去判断某个用户当天是否签到呢?因为当初表设计的时候,每个用户签到一次,即向表中插入一条记录,根据记录的数量和时间来判断用户当天是否签到。

这样的话就会有一个问题,如果是在网速过慢的情况下,用户多次点击签到按钮,那么变会发送多次请求,可能会导致一天多次签到,重复提交的问题,那么很自然的想到用事务。这次用的是spring + mybtais的框架,一开始设计的代码大致如下:

public boolean signIn(SignInHistory signInHistory) {

//编程式开启事务

TransactionTemplate template = new TransactionTemplate(transactionManager);

boolean result = (boolean) template.execute(new TransactionCallback() {

public Object doInTransaction(TransactionStatus transactionStatus) {

try {

//获取用户所有签到记录

List SignInHistoryList = signInMapper.select(signInHistory);

//如果当前时间和List中某条签到时间相同,则当天已签到,代码略去

//插入签到历史表

signInMapper.insert(signInHistory);

} catch (Exception e) {

transactionStatus.setRollbackOnly();

logger.error(e);

return false;

}

return true;

}

});

}

但是在测试中,发现还是会发生重复提交。

Mysql文档中相关说明:

Consistent read is the default mode in which InnoDB processes SELECT statements in READ COMMITTED andREPEATABLE READ isolation levels. A consistent read does not

set any locks on the tables it accesses, and therefore other sessions are free to modify those tables at the same time a consistent read is being performed on the table.

如果是在read committed和repeatab read 下,普通的select语句并不会进行锁操作。其它session可以照常更新或插入操作。

所以在这里面就可以发现,如果只是普通select,不管在不在事务中,mysql都不会将select加锁,所以根本无法阻止其它事务插入记录-------数据库事务隔离级别,只是针对一个事务能不能读取其它事务的中间结果。

背景知识

1.事务(Transaction)及其ACID属性

事务是由一组SQL语句组成的逻辑处理单元,事务具有以下4个属性,通常简称为事务的ACID属性。

原子性(Atomicity):事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。

一致性(Consistent):在事务开始和完成时,数据都必须保持一致状态。这意味着所有相关的数据规则都必须应用于事务的修改,以保持数据的完整性;事务结束时,所有的内部数据结构(如B树索引或双向链表)也都必须是正确的。

隔离性(Isolation):数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的“独立”环境执行。这意味着事务处理过程中的中间状态对外部是不可见的,反之亦然。

持久性(Durable):事务完成之后,它对于数据的修改是永久性的,即使出现系统故障也能够保持。

并发事务处理带来的问题

相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户。但并发事务处理也会带来一些问题,主要包括以下几种情况。

更新丢失(Lost Update):当两个或多个事务选择同一行,然后基于最初选定的值更新该行时,由于每个事务都不知道其他事务的存在,就会发生丢失更新问题--最后的更新覆盖了由其他事务所做的更新。例如,两个编辑人员制作了同一文档的电子副本。每个编辑人员独立地更改其副本,然后保存更改后的副本,这样就覆盖了原始文档。最后保存其更改副本的编辑人员覆盖另一个编辑人员所做的更改。如果在一个编辑人员完成并提交事务之前,另一个编辑人员不能访问同一文件,则可避免此问题。

脏读(Dirty Reads):一个事务正在对一条记录做修改,在这个事务完成并提交前,这条记录的数据就处于不一致状态;这时,另一个事务也来读取同一条记录,如果不加控制,第二个事务读取了这些“脏”数据,并据此做进一步的处理,就会产生未提交的数据依赖关系。这种现象被形象地叫做"脏读"。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值