交换一个表中的两个字段——通过临时表

 CREATE TABLE #t1(OrderId INT PRIMARY, src VARCHAR(50),Campaign VARCHAR(50))
INSERT INTO #t1(OrderId,src)
SELECT o.OrderId, src FROM CustomerInfo.dbo.Analytics_Campaign_Info(NOLOCK) AS aci
INNER JOIN Diapers.dbo.orders(NOLOCK) AS o ON aci.OrderId=o.OrderId
WHERE o.OrderDate BETWEEN '2011-08-08 00:00:00' AND GETDATE()

UPDATE a
SET a.src=b.Campaign,a.Campaign = b.src
FROM
CustomerInfo.dbo.Analytics_Campaign_Info a
INNER JOIN #t1 b ON a.OrderId=b.OrderId
### CAS操作解决ABA问题的方法与机制 #### 什么是CAS? 比较并交换(Compare-And-Swap, CAS)是一种原子指令,用于实现多线程环境下的无锁算法。它的工作原理是:如果内存中的某个位置的值等于预期旧值,则将其更新为新值;否则不进行任何操作。 然而,CAS存在所谓的 **ABA问题**,即当一个变量从状态A变为B再回到A时,另一个线程可能会错误地认为该变量从未改变过[^2]。 --- #### ABA问题的影响 假设有一个场景: - 线程T1准备使用CAS将变量V的值从A改为B。 - 在此期间,线程T2先将V的值从A改成了C,随后又从C改回了A。 - 当T1执行CAS时,由于当前值确实是A,因此CAS成功返回true。但实际上,变量的状态已经发生了变化,这可能导致逻辑上的错误或数据不一致。 这种情况下,虽然面上看起来一切正常,但由于中间发生的临时变更未被检测到,程序可能进入一种潜在危险的状态。 --- #### 如何解决ABA问题? ##### 使用带版本号的引用类 `AtomicStampedReference` Java并发包提供了`java.util.concurrent.atomic.AtomicStampedReference` 类来解决这个问题。它的核心思想是在原有值的基础上增加了一个版本戳字段(stamp),每当值发生变化时,不仅修改实际的数据内容,还会递增这个版本戳。这样即使数值本身恢复到了原来的样子,其对应的版本也会有所不同,从而能够区分出真正的变化过程[^3]。 以下是具体的操作流程描述以及代码示例: 1. 定义一个带有初始值和初始时间戳的对象实例; 2. 对每一次尝试更改都记录下最新的时间和对应的新值; 3. 如果两次之间的 stamp 不匹配,则判定条件失败,阻止非法覆盖行为发生。 ```java import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicStampedReference; public class ABADemo { public static void main(String[] args) throws InterruptedException { AtomicStampedReference<Integer> atomicRef = new AtomicStampedReference<>(100, 0); Thread t1 = new Thread(() -> { int stamp = atomicRef.getStamp(); // 获取当前的时间戳 try {Thread.sleep(50);} catch (InterruptedException e){} boolean casResult = atomicRef.compareAndSet( 100, 101, stamp, stamp + 1); System.out.println("T1 CAS Result: " + casResult); if(casResult){ casResult = atomicRef.compareAndSet( 101, 100, stamp + 1, stamp + 2); System.out.println("T1 Second CAS Result: "+casResult); } }); Thread t2 = new Thread(() -> { try{Thread.sleep(100);}catch(Exception ex){} Integer expectedValue = 100; int oldStamp = atomicRef.getStamp(); while(!atomicRef.compareAndSet(expectedValue,expectedValue+1,oldStamp,oldStamp+1)){ oldStamp=atomicRef.getStamp(); } System.out.println("T2 Changed Value To :"+atomicRef.getReference()); }); t1.start(); t2.start(); t1.join(); t2.join(); System.out.println("Final value:"+atomicRef.getReference()+", Stamp:"+atomicRef.getStamp()); } } ``` 上述代码展示了如何利用`AtomicStampedReference` 来规避传统CAS带来的ABA隐患。通过引入额外的整型标记位作为辅助判断依据之一,可以有效防止因单纯依赖目标对象本身的相等关系而导致误判的情况出现。 --- ### 总结 综上所述,针对CAS中存在的ABA缺陷,可以通过采用具备更精细控制能力的技术手段加以克服——比如借助于`AtomicStampedReference`所提供的双重验证功能即可达成目的。这种方式既保留了原有的高效特性,同时也极大地增强了系统的健壮性和可靠性。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值