2009-08-28 36 views
32

tôi đã sử dụng để thiết lập giao dịch thời gian chờ bằng cách sử dụng TransactionOptions.Timeout, nhưng đã quyết định để dễ bảo trì để sử dụng phương pháp cấu hình:Mặc định giao dịch Timeout

<system.transactions> 
    <defaultSettings timeout="00:01:00" /> 
    </system.transactions> 

Tất nhiên, sau khi đặt này vào, tôi muốn để kiểm tra nó đang hoạt động, vì vậy giảm thời gian chờ xuống còn 5 giây, sau đó chạy thử nghiệm kéo dài hơn thế này - nhưng giao dịch không xuất hiện để hủy bỏ! Nếu tôi điều chỉnh thử nghiệm để đặt TransactionOptions.Timeout thành 5 giây, thử nghiệm hoạt động như mong đợi

Sau khi điều tra, tôi cho rằng sự cố có vẻ liên quan đến TransactionOptions.Timeout, mặc dù tôi không còn sử dụng nó nữa.

Tôi vẫn cần sử dụng TransactionOptions để tôi có thể đặt IsolationLevel, nhưng tôi không còn đặt giá trị Timeout nữa, nếu tôi nhìn vào đối tượng này sau khi tạo, giá trị thời gian chờ là 00:00:00, tương đương với vô cực . Điều này có nghĩa là giá trị của tôi được đặt trong tệp cấu hình đang bị bỏ qua không?

Để tóm tắt:

  • là nó không thể trộn các thiết lập cấu hình , và sử dụng TransactionOptions
  • Nếu không, là có cách nào để trích xuất các thiết khi chạy cấu hình và sử dụng này để đặt thuộc tính Thời gian chờ Thời gian chờ
  • [Chỉnh sửa] HOẶC Đặt mức cách ly mặc định mà không sử dụng TransactionOptions
+0

Trong những tập tin cấu hình bạn đã thiết lập này? Trong phần cấu hình nào? – PVitt

+0

Trong app.confing trực tiếp dưới gốc . Cũng trong web.config's, nhưng các thử nghiệm ở trên là cho app.config. – MattH

Trả lời

44

Bạn có thể kết hợp Syst cài đặt cấu hình em.transaction và sử dụng lớp học TransactionOption, nhưng có một số điều bạn cần phải biết.

Nếu bạn sử dụng TransactionOption và định một giá trị Timeout, rằng giá trị sẽ được sử dụng trong System.Transactions/defaultTimeout giá trị.

Ở trên là mấu chốt của sự cố trong trường hợp của bạn, tôi nghĩ vậy. Bạn đang sử dụng TransactionOption để chỉ định mức độ cách ly mức và dưới dạng tác dụng phụ bạn nhận được giá trị thời gian chờ vô hạn vì vô hạn là giá trị Thời gian chờ mặc định cho TransactionOption nếu không được chỉ định. Mặc dù, tôi không hoàn toàn chắc chắn lý do tại sao đó là ... nó sẽ làm cho tinh thần để mặc định thời gian chờ giao dịch mặc định.

Bạn có thể triển khai lớp trợ giúp TransactionOptions của riêng bạn bao gồm các giá trị mặc định được đọc từ app.config (nếu tìm thấy) hoặc mặc định cho các giá trị hợp lý cho lớp TransactionOption có thể được sử dụng.

Trong mọi trường hợp, bạn vẫn có thể giới hạn điều này bằng cách sử dụng giá trị system.transaction/machineSettings/maxTimeout. Đây là một thiết lập quản trị và chỉ có thể được cấu hình thông qua machine.config. Bạn sẽ nhận được một ConfigurationException nếu bạn thử nó từ app/web.config.

<system.transactions> 
    <machineSettings maxTimeout="00:00:30" /> 
</system.transactions> 

Với maxTimeout bộ, không có vấn đề gì thời gian chờ giá trị mà bạn chỉ định, giá trị lớn nhất sẽ được giới hạn ở những giá trị maxTimeout. MaxTimeout mặc định là 00:10:00 hoặc 10 phút, vì vậy bạn sẽ không bao giờ có thời gian chờ vô hạn trên giao dịch.

Bạn cũng có thể đặt giao dịch IsolationLevel rõ ràng trên kết nối cơ sở dữ liệu bạn đang sử dụng trong giao dịch. Một cái gì đó như thế này?

var connectionString = "Server=.;Database=master;Trusted_Connection=True;"; 

      using (var scope = new TransactionScope(TransactionScopeOption.Required)) 
      { 
       using (var conn = new SqlConnection(connectionString)) 
       { 
        conn.Open(); 
        var sqlTransaction = conn.BeginTransaction(System.Data.IsolationLevel.Serializable); 

        // do database work 
        // 
        sqlTransaction.Commit(); 


       } 

       // do other work.. 
       // 

       scope.Complete(); 

      } 

Trong thử nghiệm của bạn, bạn có thể cần phải chắc chắn rằng bạn xây dựng lại để app.config được tạo lại. Trong thử nghiệm của tôi, nó xuất hiện mà tôi cần thiết để chấm dứt quá trình * .vshost.exe để nó có thể thay đổi cài đặt cấu hình system.transaction - mặc dù tôi cảm thấy rằng có thể đã là một fluke. Chỉ cần fyi ..

1

Để đưa những suy nghĩ hiện tại của tôi xuống:

  • Nó là không thể để pha trộn các thiết lập cấu hình, và sử dụng TransactionOptions
  • Cách duy nhất để trích xuất các thiết lập cấu hình tại thời gian chạy là để đọc các ứng dụng. cấu hình như một tập tin XML
  • sự cô lập cấp mặc định chỉ có thể được thực hiện thông qua tùy chọn giao dịch, hoặc theo cấp dịch vụ trong WCF sử dụng thuộc tính
+1

Đến điểm dấu đầu dòng thứ hai: có một api để truy cập tập tin cấu hình.Xem mã trong câu trả lời của tôi cho một cách để làm điều đó. Bạn không cần phải nghỉ mát để đọc nó như là một tập tin xml. –

6

Cài đặt tệp cấu hình bị bỏ qua khi sử dụng TransactionOptions. Tạo một TransactionScope sẽ, trong hầu hết các trường hợp, tạo ra một cá thể của TransactionableTransaction. Phương thức khởi tạo no arg của giao thức CommunableTransaction sẽ sử dụng thiết lập tệp cấu hình làm thời gian chờ mặc định của nó. Các nhà xây dựng TransactionScope lấy một TransactionOptions hoặc TimeSpan sẽ gọi một trong các quá tải của lớp CommectableTransaction và không phải là phiên bản không có arg. Vì vậy, nếu bạn muốn sử dụng giá trị đó, bạn phải lấy nó từ tập tin cấu hình chính mình.

Khi tôi chạy vào điều này tôi đặt đoạn mã sau trong một lớp TransactionOptionsFactory nhỏ.


Configuration configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
ConfigurationSectionGroup sectionGroup = configuration.GetSectionGroup("system.transactions"); 
DefaultSettingsSection defaultSettings = (DefaultSettingsSection) sectionGroup.Sections["defaultSettings"]; 
TransactionOptions options = new TransactionOptions(); 
options.Timeout = defaultSettings.Timeout; 
options.IsolationLevel = IsolationLevel.ReadCommitted; 
+0

Xin lỗi Mike, tôi đã trao cho bạn tiền thưởng, nhưng tôi rõ ràng là một giờ sau hạn chót tiền thưởng. Giải pháp này sẽ giải quyết vấn đề của tôi rất gọn gàng. Xấu hổ API không rõ ràng hơn về điều này. – MattH

+0

Đừng lo lắng MattH. Tôi chỉ vui vì nó đã giúp. –

46

Bạn có thể nhận thời gian chờ mặc định (đã xác thực) từ cấu hình sử dụng TransactionManager.DefaultTimeout.

TransactionOptions là cấu trúc đóng gói thời gian chờ và mức cách ly.Khi khởi tạo một struct sử dụng constructor mặc định, nó sẽ luôn luôn khởi tạo các thành viên struct để giá trị mặc định của họ:

TransactionOptions transactionOptions = new TransactionOptions(); 
transactionOptions.Timeout == default(TimeSpan); // TimeSpan.Zero 
transactionOptions.IsolationLevel == default(IsolationLevel); // IsolationLevel.Serializable 

Nếu bạn muốn chỉ định một IsolationLevel và sử dụng thời gian chờ mặc định:

new TransactionOptions() 
{ 
    IsolationLevel = IsolationLevel.Serializable, // Use whatever level you require 
    Timeout = TransactionManager.DefaultTimeout 
}; 
+0

Đây là câu trả lời tôi luôn mong đợi! Thật không may là đã quá muộn để tôi trả lời cho bạn, nhưng TransactionManager.DefaultTimeout chắc chắn là những gì tôi muốn. Cảm ơn vì đăng! – MattH

+1

Tôi cũng nhận thấy rằng Microsoft cũng sử dụng kỹ thuật này trong [tài liệu về System.Transactions] của họ [http://msdn.microsoft.com/en-us/library/ms973865.aspx). Cảm ơn thông tin hữu ích! –

+0

FWIW Groveling trong ILSpy hiển thị mặc định là 1 phút trong .NET 4.0, hãy nhớ đây là chi tiết triển khai, do đó, có thể thay đổi, sử dụng ở trên để kiểm tra lại giá trị này !: // System.Transactions.Configuration.DefaultSettingsSection [ConfigurationProperty ("timeout", DefaultValue = "00:01:00"), TimeSpanValidator (MinValueString = "00:00:00", MaxValueString = "10675199.02: 48: 05.4775807")] – aolszowka

9

mỗi Reflector , các quy tắc cơ bản để đặt thời gian giao dịch với các nhà thầu của TransactionScope như sau:

DefaultTimeOut được xác định bởi các quy tắc đầu tiên từ bên dưới đó là hài lòng:

  • nếu các nhà xây dựng có một tham số TimeSpan, các DefaultTimeout là rằng tham số
  • nếu các nhà xây dựng có một tham số TransactionOption, các DefaultTimeout là transactionOption.TimeOut
  • nếu hàm tạo có tham số TransactionScopeOption, DefaultTimeout là scopeOption.TimeOut
  • nếu hàm tạo không có tham số hết thời gian chờ, DefaultTimeout là giá trị được chỉ định trong tệp cấu hình ứng dụng hoặc web.
  • nếu không, DefaultTimeOut là 1 phút.

MaxTimeOut là 10 phút trừ khi giá trị khác được chỉ định trong machine.config.

thời gian chờ hiệu lực cho giao dịch nhỏ hơn MaxTimeOut và DefaultTimeOut lớn hơn 0. Nếu cả MaxTimeOut và DefaultTimeOut đều bằng không, thời gian chờ hiệu dụng là số lượng ve được biểu thị bằng long.MaxValue (vô cùng).

Nếu cá thể TransactionScope không tạo giao dịch mới vì giao dịch được chuyển vào hàm tạo hoặc do tùy chọn phạm vi giao dịch không yêu cầu (ví dụ: khi giao dịch môi trường xung quanh và Giao dịch được yêu cầu), nhưng thông số timeOut vẫn được truyền trong hàm khởi tạo, bộ hẹn giờ được bắt đầu. Khi hết thời gian chờ, phương thức TimeOut() của giao dịch cơ bản được gọi. Các thuộc tính DefaultTimeOut và MaxTimeOut không được sử dụng trong trường hợp này.

Nếu số transactionScopeOption == TransactionScopeOption.Supress, thời gian chờ bị bỏ qua và không có hiệu lực.

Nó cũng có thể để xác định MaxTimeOut trong tập tin cấu hình ứng dụng/web, nếu phần có liên quan trong Machine.config sẽ bị thay thế (chú ý các giá trị của allowDefintion và allowExeDefinition thuộc tính):

<sectionGroup name="system.transactions" type="System.Transactions.Configuration.TransactionsSectionGroup, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"> 
    <section name="defaultSettings" type="System.Transactions.Configuration.DefaultSettingsSection, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null"/> 
    <section name="machineSettings" type="System.Transactions.Configuration.MachineSettingsSection, System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, Custom=null" allowDefinition="MachineToApplication" allowExeDefinition="MachineToApplication"/> 
</sectionGroup> 

để tham khảo nhanh chóng, sau đây là các nhà thầu TransactionScope:

public TransactionScope(Transaction transactionToUse, TimeSpan scopeTimeout, EnterpriseServicesInteropOption interopOption); 
public TransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions, EnterpriseServicesInteropOption interopOption); 
public TransactionScope(TransactionScopeOption scopeOption, TransactionOptions transactionOptions); 
public TransactionScope(TransactionScopeOption scopeOption, TimeSpan scopeTimeout); 
public TransactionScope(Transaction transactionToUse, TimeSpan scopeTimeout); 
public TransactionScope(TransactionScopeOption scopeOption); 
+0

Câu trả lời thú vị! – buckley

1
void Main() 
{ 
    var maximumTimeout = TransactionManager.MaximumTimeout;//This step is necessary to init _maximumTimeout value, 

    FieldInfo fieldInfo = typeof(TransactionManager).GetFields(BindingFlags.NonPublic | BindingFlags.Static).Single(item => item.Name == "_maximumTimeout"); 
    var customMaximumTimeout = TimeSpan.FromHours(1); 
    fieldInfo.SetValue(null, customMaximumTimeout); 
    maximumTimeout = TransactionManager.MaximumTimeout; 

    Console.WriteLine(maximumTimeout);//01:00:00 
    // use TransactionScope 
} 
+0

Như Franz chỉ ra một cách chính xác - bạn có thể làm điều này với sự phản chiếu. Tôi tìm thấy một phương pháp khác trong các ý kiến ​​của bài viết MSDN này: http://blogs.msdn.com/b/ajit/archive/2008/06/18/override-the-system-transactions-default-timeout-of-10- phút-in-the-code.aspx # 10417962 - tiếc là tình hình DevOps tại công ty của tôi không phải là những gì tôi cần nó để được như vậy tôi không có một cách dễ dàng để cập nhật machine.config trên tất cả các nút xử lý và có các cài đặt được áp dụng cho các cài đặt trong tương lai. Sử dụng sự phản chiếu là một giải pháp tốt cho tôi. –

Các vấn đề liên quan