标签:
比如 一张表 user (id,name) 在 id主键上建有检索。
测试:
1.建一张表users
Create Table: CREATE TABLE `users` (
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
插入数据:
+----+------+
| id | name |
+----+------+
| 1 | a |
| 2 | b |
+----+------+
2.测试代码:
new Thread() { public void run() { try { Connection conn = getConn(); conn.setAutoCommit(false); PreparedStatement ps = conn .prepareStatement("select * from users where id=1 for update"); ResultSet rs=ps.executeQuery(); rs.next(); String name=rs.getString("name"); TimeUnit.SECONDS.sleep(30); if(name.equals("a")) ps.execute("update users set name='线程1' where id=1"); conn.commit(); conn.close(); } catch (Exception e) { // TODO: handle exception }finally{ } }; }.start(); new Thread() { public void run() { try { Connection conn = getConn(); conn.setAutoCommit(false); PreparedStatement ps = conn .prepareStatement("update users set name='线程2' where id=1"); ps.execute(); conn.commit(); conn.close(); } catch (Exception e) { // TODO: handle exception } }; }.start();
说明 :1)当线程1 不用 for update 锁住id=1 记录 结果name=线程1 。
2)当线程1 使用 for update锁住id=1记录 ,线程2 在执行ps.execute();会阻塞 ,等待获取锁,说明 记录被锁住时候,不能写入。
总结 :
(1)线程1执行‘select * from users where id=1 for update’ 锁住该行 ,线程2执行‘update users set name=‘线程2‘ where id=1’,更改这条记录时候会阻塞,需要等带 线程1 commmit 该事物。补充 如果线程执行 查询((不加for update)) 则不会被阻塞(select * from users where id=1)。
(2)id=1记录被锁住,线程2 可以更新其他记录。
(3)如果改为‘select * from users where for update’ 则是table lock。则需要等待commmit 其他线程才可以更新 其中任何记录。其他线程查询(不加for update)不受影响。其他线程查询(加for update),如‘select * from users for update’会阻塞。
标签:
原文地址:http://blog.csdn.net/taotoxht/article/details/45966753