Accessing the current transaction
At this point you may be wondering, "How do they know that there is a transaction active in the SQLCLR code to automatically enlist ADO.NET connections?" It turns out that integration goes deeper.
Outside of SQL Server, the System Transactions framework exposes the concept of a "current transaction," which is available through System.Transaction.Current. We basically did the same thing inside the server.
If a transaction was active at the point where SQLCLR code is entered, then the transaction will be surfaced to the SQLCLR API through the System.Transactions.Transaction class. Specifically, Transaction.Current will be non-null.
In most cases you don't need to access the transaction explicitly. For database connections, ADO.NET will check Transaction.Current automatically during connection Open() and it will enlist the connection in that transaction transparently (unless you add enlist=false to the connection string).
There are a few scenarios where you might want to use the transaction object directly:
If you want to abort the external transaction from within your stored procedure or function. In this case, you can simply call Transaction.Current.Rollback().
If you want to enlist a resource that doesn't do automatic enlistment, or for some reason wasn't enlisted during initialisation.
You may want to enlist yourself in the transaction, perhaps to be involved in the voting process or just to be notified when voting happens.
Note that although I used a very explicit example where I do a BEGIN TRAN, there other scenarios where your SQLCLR code can be invoked inside a transaction and Transaction.Current will be non-null. For example, if you invoke a managed user-defined function within an UPDATE statement, it will happen within a transaction even if one wasn't explicitly started.
Using System.Transactions explicitly
If you have a block of code that needs to execute within a transaction even if the caller didn't start one, you can use the System.Transactions API. This is, again, the same code you'd use in the client or middle-tier to manage a transaction. For example: