简体   繁体   English

从WCF客户端传播到WCF服务的事务的隔离是什么意思?

[英]What is the meaning of Isolation for a transaction that propagates from WCF client to WCF service?

Question

There are three parts to this question: 这个问题分为三个部分:

  1. Why does a Serializable transaction not perform operations atomically? 为什么可序列化事务不能自动执行操作?
  2. Assuming that the answer is that atomicity of a transaction does not guarantee atomicity of its constituent operations (and that it only ensures that all operations either all succeed or all fail), why does the Isolation requirement of the transaction not ensure that the operations are atomic? 假设答案是事务的原子性不能保证其组成操作的原子性(并且只能确保所有操作要么全部成功要么全部失败),为什么事务的隔离要求不能确保该操作是原子性的? I have read that the Serializable isolation level ensures that transactions are executed as if they were executed serially? 我已经读过,可序列化隔离级别可确保事务像串行执行一样被执行?
  3. If my interpretation of Isolation is not correct, what is the correct interpretation and how could I modify the test to demonstrate the difference between the use of Serialized transaction as oppose to not using a transaction at all. 如果我对隔离的解释不正确,那么什么是正确的解释?我如何修改测试以证明使用序列化事务与完全不使用事务之间的区别。

A Minimal Complete and Verifiable example 最小完整且可验证的示例

The code can be downloaded from here 可以从这里下载代码

Assume that the DataLayer (DAL) is implemented by a WCF service and that the client side code consists of a call to its operations from Main: 假定DataLayer(DAL)是由WCF服务实现的,并且客户端代码包括从Main对其操作的调用:

    public void Main(string[] args)
    {
        var dal = new DataLayerServiceClient();

        var accounts = dal.GetAccounts();
        int accountId = accounts.First().AccountId;

        for (int i = 0; i < 10000; i++)
        {
            using (TransactionScope scope = new TransactionScope())
            {
                var account = dal.GetAccountById(accountId);
                account.Balance++;
                dal.Update(account);

                scope.Complete();
            }
        }
    }

Assume also: 还假设:

  1. The client and the service are configured correctly to propagate client transactions to the service. 客户端和服务已正确配置为将客户端事务传播到服务。 (This was verified on the service side by observing that there is an ambient transaction, that it has a distributed identifier and that the identifier is the same as the one on the client side. (这是在服务端通过观察环境事务来验证的,该事务具有分布式标识符,并且该标识符与客户端的标识符相同。
  2. The isolation mode of the transaction (both in the service and on the client) is Serializable (verified by observing the properties of the ambient Transaction on service and client) 事务的隔离模式(在服务中和在客户端上)都是可序列化的(通过观察服务和客户端上的环境事务的属性来验证)

Test Description 测试说明

Run two client processes concurrently. 同时运行两个客户端进程。

Expected Result 预期结果

The expected result is that the balance of the account after both clients exit should be 20000 larger than it was before both clients started. 预期结果是两个客户退出后的帐户余额应比两个客户都启动前的帐户余额大20000。

Actual Result 实际结果

The balance of the account after both clients exit is a value between 10000 and 20000. In some cases, one of the client is aborted due to the following error: 两个客户端退出后帐户的余额在10000到20000之间。在某些情况下,其中一个客户端由于以下错误而中止:

Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim 事务(进程ID)已与另一个进程在锁定资源上发生死锁,并已被选择为死锁受害者

Conclusion 结论

The operations contained within the scope of the TransactionScope on each client did not run as a whole in series with those of the other client. 每个客户端上的TransactionScope范围内包含的操作并未与另一个客户端上的整体串联运行。 Reads and writes from both transactions were mixed and some of the increments were lost. 来自两个事务的读取和写入混合在一起,并且某些增量丢失了。

  1. Question : "Why does a Serializable transaction not perform operations atomically" 问题 :“为什么可序列化事务不能自动执行操作”
    Answer : A Serializable transaction is atomic in the sense that all its operations will either all succeed or all fail. :可序列化事务是原子性的,这意味着它的所有操作都将全部成功或全部失败。 This is not refuted by the example. 这个例子没有反驳。
  2. Question : "Why does the Isolation requirement of the transaction not ensure that the operations are atomic? 问题 :“为什么事务的隔离要求不能确保操作是原子性的?
    Answer : Two Serializable transactions meet the Isolation requirement in that they will not run concurrently. :两个可序列化的事务满足隔离要求,因为它们不会同时运行。 If two try to run together, one will continue as planned and the other is aborted. 如果两个尝试一起运行,则一个将按计划继续,而另一个将中止。 This is precisely why the exception that is reported in the question occurred. 这正是问题中报告的异常发生的原因。 ("Transaction (Process ID) was deadlocked on lock resources with another process and has been chosen as the deadlock victim"). (“事务(进程ID)与另一个进程在锁资源上死锁,并已被选择为死锁受害者”)。
  3. Question : "If my interpretation of Isolation is not correct, what is the correct interpretation?". 问题 :“如果我对隔离的解释不正确,那么正确的解释是什么?”。
    Answer : The incorrect assumption in the question is that if two transactions cannot run concurrently, one will wait for the other to complete and then proceed. :问题中的错误假设是,如果两个事务不能同时运行,则一个事务将等待另一个事务完成然后继续。 This is not correct. 这是不正确的。 Indeed Serializable transactions are isolated and will not run concurrently, but that does not mean that one will wait for the other. 实际上,可序列化事务是隔离的,不会并行运行,但这并不意味着一个将等待另一个。 Isolation of transactions is not the same as holding a mutex in order to perform a set of operations in isolation. 事务隔离与持有互斥锁以独立执行一组操作不同。
    Question : "and how could I modify the test to demonstrate the difference between the use of Serialized transaction as oppose to not using a transaction at all" 问题 :“以及如何修改测试以证明使用序列化事务与完全不使用事务之间的区别”
    Answer : The following snippet would demonstrate the use of transactions to assure that increment occurs as expected. :以下代码片段将演示如何使用事务来确保按预期进行增量。

      int i = 0; while(i < 10000) { try { using (TransactionScope scope = new TransactionScope()) { var account = dal.GetAccountById(accountId); account.Balance++; dal.Update(account); scope.Complete(); } i++; } catch (Exception ex) { Console.WriteLine($"{ex.Message} : restarting"); } } 

Of course this is extremely inefficient but it works as expected and demonstrates how transactions isolate operations on resource managers. 当然,这效率极低,但是可以按预期工作,并演示了事务如何隔离资源管理器上的操作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM