用@Transaction来定义方法,方法里有读库,也有写库。事务和同步之间会不会有什么关联呢?如果事务太长会不会影响到访问呢?会不会造成死锁呢?
如何才能高效使用事务机制呢?现在对事务有点不太了解。
但我也有了一些自己的理解,但不知道对不对:
事务和同步在mysql里是两个层级的概念。事务架于同步层之上。事务是一个业务层的概念,而同步时资源层的概念。当事务里对同一条记录进行Update的操作的时候,可定会出现同步问题,但这是无法避免的。根据层次思想,第n层调用第n-1层。我们所能做的就是设计好业务层,定义好表,别出现不同用户update同一条记录的情况(这种情况几乎很难遇到)。
事务的ACID原则在某种程度上也使得第n层的事务和第n-1层的资源层之间的“理还乱”的关系清晰了些。
但,oracle中的多个隔离级别又是怎么一回事?
再大胆来个猜想:数据库ACID的实现
基本思想:
1 COW(copy on write)
2 每一个表都有一个static的位置指针,供多个线程同时insert时使用
3 insert,update这些操作在insert,update到copy区域时会进行类型,长度,唯一性等检查。如果能执行,在commit后,直接把该区域复制到真正的表空间中,由static pos指示。pos需要同步。
oschina.net弹出来的文章对我有帮助:http://my.oschina.net/shangjx13/blog/78882
其中说到了FOR UPDATE
BEGIN;
SELECT book_number FROM book WHERE book_id = 123 FOR UPDATE;
// ...
UPDATE book SET book_number = book_number - 1 WHERE book_id = 123;
COMMIT;
由 于加入了FOR UPDATE,所以会在此条记录上加上一个行锁,如果此事务没有完全结束,那么其他的事务在使用SELECT ... FOR UPDATE请求的时候就会处于等待状态,直到上一个事务结束,它才能继续,从而避免了问题的发生,需要注意的是,如果你其他的事务使用的是不带FOR UPDATE的SELECT语句,将得不到这种保护。
今天读spring in action一书,对上述疑问有了一些理解:
I :isolation
事务应该允许多个用户操作同一个数据,一个用户的操作不会和其他用户的操作相混淆。因此,事务必须是互相隔离的,防止并发读写同一个数据的情况发生。(注意,隔离通常意味着要锁定数据库里的记录和(或)整张表)