diff --git a/moto/dynamodb2/exceptions.py b/moto/dynamodb2/exceptions.py
--- a/moto/dynamodb2/exceptions.py
+++ b/moto/dynamodb2/exceptions.py
@@ -174,6 +174,13 @@ def __init__(self, errors):
         super().__init__(msg)
 
 
+class MultipleTransactionsException(MockValidationException):
+    msg = "Transaction request cannot include multiple operations on one item"
+
+    def __init__(self):
+        super().__init__(self.msg)
+
+
 class EmptyKeyAttributeException(MockValidationException):
     empty_str_msg = "One or more parameter values were invalid: An AttributeValue may not contain an empty string"
     # AWS has a different message for empty index keys
diff --git a/moto/dynamodb2/models/__init__.py b/moto/dynamodb2/models/__init__.py
--- a/moto/dynamodb2/models/__init__.py
+++ b/moto/dynamodb2/models/__init__.py
@@ -23,6 +23,7 @@
     TransactionCanceledException,
     EmptyKeyAttributeException,
     InvalidAttributeTypeError,
+    MultipleTransactionsException,
 )
 from moto.dynamodb2.models.utilities import bytesize
 from moto.dynamodb2.models.dynamo_type import DynamoType
@@ -1566,6 +1567,14 @@ def describe_time_to_live(self, table_name):
     def transact_write_items(self, transact_items):
         # Create a backup in case any of the transactions fail
         original_table_state = copy.deepcopy(self.tables)
+        target_items = set()
+
+        def check_unicity(table_name, key):
+            item = (str(table_name), str(key))
+            if item in target_items:
+                raise MultipleTransactionsException()
+            target_items.add(item)
+
         errors = []
         for item in transact_items:
             try:
@@ -1573,6 +1582,7 @@ def transact_write_items(self, transact_items):
                     item = item["ConditionCheck"]
                     key = item["Key"]
                     table_name = item["TableName"]
+                    check_unicity(table_name, key)
                     condition_expression = item.get("ConditionExpression", None)
                     expression_attribute_names = item.get(
                         "ExpressionAttributeNames", None
@@ -1611,6 +1621,7 @@ def transact_write_items(self, transact_items):
                     item = item["Delete"]
                     key = item["Key"]
                     table_name = item["TableName"]
+                    check_unicity(table_name, key)
                     condition_expression = item.get("ConditionExpression", None)
                     expression_attribute_names = item.get(
                         "ExpressionAttributeNames", None
@@ -1629,6 +1640,7 @@ def transact_write_items(self, transact_items):
                     item = item["Update"]
                     key = item["Key"]
                     table_name = item["TableName"]
+                    check_unicity(table_name, key)
                     update_expression = item["UpdateExpression"]
                     condition_expression = item.get("ConditionExpression", None)
                     expression_attribute_names = item.get(
@@ -1648,6 +1660,10 @@ def transact_write_items(self, transact_items):
                 else:
                     raise ValueError
                 errors.append(None)
+            except MultipleTransactionsException:
+                # Rollback to the original state, and reraise the error
+                self.tables = original_table_state
+                raise MultipleTransactionsException()
             except Exception as e:  # noqa: E722 Do not use bare except
                 errors.append(type(e).__name__)
         if any(errors):
diff --git a/moto/dynamodb2/responses.py b/moto/dynamodb2/responses.py
--- a/moto/dynamodb2/responses.py
+++ b/moto/dynamodb2/responses.py
@@ -1127,6 +1127,9 @@ def transact_write_items(self):
         except TransactionCanceledException as e:
             er = "com.amazonaws.dynamodb.v20111205#TransactionCanceledException"
             return self.error(er, str(e))
+        except MockValidationException as mve:
+            er = "com.amazonaws.dynamodb.v20111205#ValidationException"
+            return self.error(er, mve.exception_msg)
         response = {"ConsumedCapacity": [], "ItemCollectionMetrics": {}}
         return dynamo_json_dump(response)
 

Thanks @Guriido - marking it as an enhancement to implement this validation.
diff --git a/tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py b/tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py
--- a/tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py
+++ b/tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py
@@ -1,12 +1,10 @@
 import boto3
 import pytest
 import sure  # noqa # pylint: disable=unused-import
-
-from botocore.exceptions import ClientError
 from boto3.dynamodb.conditions import Key
+from botocore.exceptions import ClientError
 from moto import mock_dynamodb2
 
-
 table_schema = {
     "KeySchema": [{"AttributeName": "partitionKey", "KeyType": "HASH"}],
     "GlobalSecondaryIndexes": [
@@ -466,3 +464,41 @@ def test_creating_table_with_0_global_indexes():
     err["Message"].should.equal(
         "One or more parameter values were invalid: List of GlobalSecondaryIndexes is empty"
     )
+
+
+@mock_dynamodb2
+def test_multiple_transactions_on_same_item():
+    table_schema = {
+        "KeySchema": [{"AttributeName": "id", "KeyType": "HASH"}],
+        "AttributeDefinitions": [{"AttributeName": "id", "AttributeType": "S"},],
+    }
+    dynamodb = boto3.client("dynamodb", region_name="us-east-1")
+    dynamodb.create_table(
+        TableName="test-table", BillingMode="PAY_PER_REQUEST", **table_schema
+    )
+    # Insert an item
+    dynamodb.put_item(TableName="test-table", Item={"id": {"S": "foo"}})
+
+    def update_email_transact(email):
+        return {
+            "Update": {
+                "Key": {"id": {"S": "foo"}},
+                "TableName": "test-table",
+                "UpdateExpression": "SET #e = :v",
+                "ExpressionAttributeNames": {"#e": "email_address"},
+                "ExpressionAttributeValues": {":v": {"S": email}},
+            }
+        }
+
+    with pytest.raises(ClientError) as exc:
+        dynamodb.transact_write_items(
+            TransactItems=[
+                update_email_transact("test1@moto.com"),
+                update_email_transact("test2@moto.com"),
+            ]
+        )
+    err = exc.value.response["Error"]
+    err["Code"].should.equal("ValidationException")
+    err["Message"].should.equal(
+        "Transaction request cannot include multiple operations on one item"
+    )

DynamoDb2.client.transact_write_items transactions on same item
transact_write_items does not allow several transactions on the same item

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/dynamodb.html#DynamoDB.Client.transact_write_items
> TransactWriteItems is a synchronous write operation that groups up to 25 action requests. These actions can target items in different tables, but not in different Amazon Web Services accounts or Regions, and no two actions can target the same item

moto should also fail the transaction in this case (currently one can perform two transactions on the same item)

tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_multiple_transactions_on_same_item
tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_put_item_wrong_attribute_type tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_update_item_range_key_set tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_query_gsi_with_wrong_key_attribute_names_throws_exception tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_empty_expressionattributenames_with_empty_projection tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_create_table_with_missing_attributes tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_hash_key_can_only_use_equals_operations[<] tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_empty_expressionattributenames_with_projection tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_empty_expressionattributenames tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_hash_key_can_only_use_equals_operations[>=] tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_create_table_with_redundant_attributes tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_creating_table_with_0_local_indexes tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_hash_key_cannot_use_begins_with_operations tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_create_table_with_redundant_and_missing_attributes tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_hash_key_can_only_use_equals_operations[<=] tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_batch_write_item_non_existing_table tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_creating_table_with_0_global_indexes tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_hash_key_can_only_use_equals_operations[>] tests/test_dynamodb2/exceptions/test_dynamodb_exceptions.py::test_batch_get_item_non_existing_table