赞
踩
下面表需要加索引为行锁,不加索引为表锁
①.查询和修改必须在一个事务中
- /**
- * 更新Inter数据
- */
- @Override
- @Transactional
- public void updateInterData() {
- InterBean interBean = interMapper.queryInterData("interface1");
- Long interUrl = interBean.getInterUrl();
- interUrl+=1;
- interBean.setInterUrl(interUrl);
- interMapper.updateInterData(interBean);
- }
②. 查询语句末尾需要加for update
- <select id="queryInterData" resultMap="baseResult">
- select id,inter_number,inter_url from interface.lock_test_table where inter_number =#{interNumber} for update
- </select>
- public class SynchronizedObjectLock implements Runnable {
- static SynchronizedObjectLock instence = new SynchronizedObjectLock();
-
- @Override
- public void run() {
- // 同步代码块形式——锁为this,两个线程使用的锁是一样的,线程1必须要等到线程0释放了该锁后,才能执行
- synchronized (this) {
- System.out.println("我是线程" + Thread.currentThread().getName());
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println(Thread.currentThread().getName() + "结束");
- }
- }
-
- public static void main(String[] args) {
- Thread t1 = new Thread(instence);
- Thread t2 = new Thread(instence);
- t1.start();
- t2.start();
- }
- }
lock()
: 加锁unlock()
: 解锁tryLock()
: 尝试获取锁,返回一个boolean值tryLock(long,TimeUtil)
: 尝试获取锁,可以设置超时Lock一般使用的例子,注意ReentrantLock是Lock接口的实现。
- package com.hjt.lock;
-
-
- import java.util.concurrent.locks.Lock;
- import java.util.concurrent.locks.ReentrantLock;
-
- public class LockTest {
- private Lock lock = new ReentrantLock();
-
- //需要参与同步的方法
- private void method(Thread thread){
- try {
- lock.lock();
- System.out.println("线程名"+thread.getName() + "获得了锁");
- }catch(Exception e){
- e.printStackTrace();
- } finally {
- lock.unlock();
- System.out.println("线程名"+thread.getName() + "释放了锁");
-
- }
- }
-
- public static void main(String[] args) {
- LockTest lockTest = new LockTest();
-
- //线程1
- Thread t1 = new Thread(new Runnable() {
-
- @Override
- public void run() {
- lockTest.method(Thread.currentThread());
- }
- }, "t1");
-
- Thread t2 = new Thread(new Runnable() {
-
- @Override
- public void run() {
- lockTest.method(Thread.currentThread());
- }
- }, "t2");
-
- t1.start();
- t2.start();
- }
- }
- //执行情况:线程名t1获得了锁
- // 线程名t1释放了锁
- // 线程名t2获得了锁
- // 线程名t2释放了锁
CAS操作包括了3个操作数:
- 1) 需要读写的内存位置(V)
- 2) 进行比较的预期值(A)
- 3) 拟写入的新值(B)
数据库中添加version字段
取出记录时,获取当前version
SELECT id,`name`,price,`version` FROM product WHERE id=1
更新时,version + 1,如果where语句中的version版本不对,则更新失败
UPDATE product SET price=price+50, `version`=`version` + 1 WHERE id=1 AND`version`=1
修改实体类
- @Data
- public class Product {
- private Long id;
- private String name;
- private Integer price;
- @Version //标识乐观锁版本号字段
- private Integer version;
- }
添加乐观锁插件配置
- @Configuration
- //扫面指定的mapper包
- @MapperScan("com.xin.mybatisplus2.mapper")
- public class MyBatisPlusConfig {
- @Bean
- public MybatisPlusInterceptor mybatisPlusInterceptor() {
- MybatisPlusInterceptor interceptor=new MybatisPlusInterceptor();
- //new PaginationInnerInterceptor(DbType.MYSQL):创建分页插件,数据库类型是MySQL
- interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
- //添加乐观锁插件
- interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
- return interceptor;
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。