SaveChanges is automatically transactional: that is, if more than one entity needs to be saved, LightSpeed guarantees that the changes to the database will be atomic and durable (provided the database supports transactions). To achieve this, SaveChanges automatically begins a transaction before sending the first change, and commits it after sending the last change if all changes have been successful.
As far as LightSpeed is concerned, however, each SaveChanges is an independent transaction. If you need multiple LightSpeed operations to be part of a single transaction, you must specify that transaction yourself.
The easiest way to control transactions with LightSpeed is to use the .NET TransactionScope class. To do this, simply surround any calls to IUnitOfWork with the standard TransactionScope block:
Using a system transaction with a LightSpeed unit of work
using (var transactionScope = new TransactionScope())
However, not all data providers support TransactionScope. (Specifically, at the time of writing, Oracle and PostgreSQL do not.)
For these cases, IUnitOfWork exposes a BeginTransaction method. This method returns a standard ADO.NET IDbTransaction object. In this case, the usage pattern is slightly different as we need to flush changes using the IUnitOfWork.SaveChanges method before committing the transaction and then completing the unit of work.
Using an ADO.NET transaction with a LightSpeed unit of work
using (var unitOfWork = _context.CreateUnitOfWork())
Remember that you only need to manually specify a transaction if you need to coordinate at a larger scope than a single SaveChanges. LightSpeed automatically ensures that all database flush operations run within a transaction. In most cases therefore you will not need to create transactions explicitly.