关于mysql 的for update

比如 一张表 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’会阻塞。

时间: 2024-12-05 03:46:11

关于mysql 的for update的相关文章

mysql 多表 update sql语句总结

mysql 多表 update 有几种不同的写法. 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是ProductPrice表,我们要将ProductPrice表中的价格字段Price更新为Price表中价格字段的80%. 在Mysql中我们有几种手段可以做到这一点,一种是update table1 t1, table2 ts ...的方式: UPDATE product p, productPrice pp SET pp.price = pp.p

mysql SELECT FOR UPDATE语句使用示例

以MySQL 的InnoDB 为例,预设的Tansaction isolation level 为REPEATABLE READ,在SELECT 的读取锁定主要分为两种方式:SELECT ... LOCK IN SHARE MODE SELECT ... FOR UPDATE这两种方式在事务(Transaction) 进行当中SELECT 到同一个数据表时,都必须等待其它事务数据被提交(Commit)后才会执行.而主要的不同在于LOCK IN SHARE MODE 在有一方事务要Update 同

MySQL中SELECT+UPDATE处理并发更新问题解决方案

这篇文章主要介绍了MySQL中SELECT+UPDATE处理并发更新问题解决方案分享,需要的朋友可以参考下. 问题背景 假设MySQL数据库有一张会员表vip_member(InnoDB表),结构如下: 当一个会员想续买会员(只能续买1个月.3个月或6个月)时,必须满足以下业务要求: 如果end_at早于当前时间,则设置start_at为当前时间,end_at为当前时间加上续买的月数 如果end_at等于或晚于当前时间,则设置end_at=end_at+续买的月数 续买后active_statu

Mysql Insert Or Update语法例子

Mysql Insert Or Update语法例子 有的时候会需要写一段insert的sql,如果主键存在,则update:如果主键不存在,则insert.Mysql中提供了这样的用法:ON DUPLICATE KEY UPDATE.下面就看看它是如何使用的吧! 首先数据库的原始数据如下: a b c 1 b1 c1 2 b2 c2 3 b3 c3 此时如果执行下面的sql就会报错 INSERT INTO test VALUES(1,'b4','c4'); 报错信息如下,提示无法重复插入: 1

MySQL中进行update/delete操作时,发生 Error Code: 1175

问题为个人遇到记录,各位大牛免喷. 在MYSQL的一张表进行 update 操作时,发现不能操作,发生如下错误. 在对 对于此问题, 原因:MYSQL的安全机制造成的,默认是不允许随意进行 删改 数据. 解决办法 : 将安全机制降低, 执行如下语句即可  set sql_safe_updates = 0; 如图:可成功执行update语句

bash中使用mysql中的update命令

mysql -uroot -ppasswd -e "update tbadmin set sPassword ='************' where sUserName='admin'" database mysql客户端命令行有一个参数是 -e,即运行制定SQL命令.例如 mysql -uxx -pxx -e"select * from table" database

Update MySQL timestamp on update

MySQL timestamp FAQ: How can I update a MySQL TIMESTAMP field when I issue an update for a MySQL database table? MySQL has some crazy rules about how timestamp fields can be created, but one nice "timestamp update" syntax you can use looks like

在MySQL中阻止UPDATE语句没有添加WHERE条件的发生

如果在生产环境中使用UPDATE语句更新表数据,此时如果忘记携带本应该添加的WHERE条件,那么..Oh,no…后果可能不堪设想.那么有没有什么办法可以阻止这样的事情发生,又不使用任何的审核工具呢...办法当然是有的 sql_safe_updates sql_safe_updates这个MySQL自带的参数就可以完美的解决我们的问题,并且该参数是可以在线变更的哦~当该参数开启的情况下,你必须要在UPDATE语句后携带WHERE条件,否则就会报出ERROR.. 举个栗子 # sql_safe_up

mysql save or update

原文:http://www.bitscn.com/pdb/mysql/201503/473268.html 背景   在平常的开发中,经常碰到这种更新数据的场景:先判断某一数据在库表中是否存在,存在则update,不存在则insert. 如果使用Hibernate,它自带saverOrUpdate方法,用起来很方便,但如使用原生sql语句呢?   新手最常见的写法是,先通过select语句查询记录是否存在,存在则使用update语句更新,不存在则使用insert语句插入. 但是这样做明显不够优雅

Sql Server 与 MySql 在使用 update inner join 时的区别

Sql Server update tb_User set pass = ''-- 此处pass前不要加 tb_User 别名usr from tb_User usr inner join tb_Address addr on usr.nAddressFK = addr.nAddressID where usr.id=123 MySql UPDATE mem_world AS mw1 INNER JOIN mem_world AS mw2 ON mw1.parentid = mw2.wid SE